<?php


/**
 *  Copyright 2010 KEYRIO Licensed under the Apache License, 
 *  Version 2.0 (the "License"); you may not use this file except in compliance 
 *  with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
 *  Unless required by applicable law or agreed to in writing, software distributed 
 *  under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 *  either express or implied. See the License for the specific language governing 
 *  permissions and limitations under the License. 
 *  
 * @author Johan Leche - <j.leche@keyrio.fr>
 * 
 * 10/02/2010
 * v0.0.1b
 *
 */

class CHCChart extends AbstractHCObject
{
    private $m_sId;
    private $m_asColors = array();
    private $m_aoSeries = array();
    public  $setTitle;
    public  $setSubTitle;
    public  $setXAxis;
    public  $setYAxis;
    public  $setTooltip;
    public  $setLegend;
    static  $sm_asTokenizer = array();
    
    
    /**
     * Instanciate the Chart Object.
     * You can specify the id of the container, or let CHCChart 
     * generate it (and access to it later with the this->getId() Method)  
     * 
     * @param String $psId
     */
    public function __construct($psId = '')
    {
        $this->setTitle        = new CHCTitle();
        $this->setSubTitle     = new CHCTitle();
        $this->setXAxis        = new CHCAxis();
        $this->setYAxis        = new CHCAxis();
        $this->setTooltip      = new CHCTooltip();
        $this->setLegend       = new CHCLegend();
        $this->setId($psId);
        
        $this->setParam('renderTo', $this->getId());
        $this->setParam('defaultSeriesType', 'line');
        $this->setMargin(array(50, 150, 60, 80));
        
        // If a javascript manager is used, we include all the libraries here
        if (class_exists('CSJavascriptManager'))
        {
            CSJavascriptManager::useJSLib(CONST_LIB_JS_JQUERY);
            CSJavascriptManager::addPath('framework/libs/js/highCharts/highcharts.js');
            CSJavascriptManager::addPath('framework/libs/js/highCharts/highcharts.js');
        }

    }
    
    
    /**
     * Return the Id of the chart's container
     * 
     * If Empty, it is generated
     * 
     */
    public function getId()
    {
        if (empty($this->m_sId))
            $this->setId(uniqid('id_'));
            
        return $this->m_sId;    
    }
    
    
    /**
     * Set the Id of the container
     * 
     * @param $psString
     */
    public function setId($psString)
    {
        if (CSDebug::assertString($psString)) return false;
        
        $this->m_sId = $psString;
    }
    
    
    /**
     * Shortcut to CHCTitle::setText();
     * 
     * @param String $psString
     */
    public function setTitle($psString)
    {
        $this->setTitle->setText($psString);
    }
    
    
    /**
     * Shortcut to CHCTitle::setText();
     * 
     * @param String $psString
     */
    public function setSubTitle($psString)
    {
        $this->setSubTitle->setText($psString);
    }
    
    
    /**
     * Set the margin of the chart's container
     * 
     * @param $pasArray
     */
    public function setMargin($pasArray)
    {
        if (CSDebug::assertArray($pasArray)) return false;
        
        $this->setParam('margin', $pasArray);
    }
    
    
    /**
     * Add a CHCSeries object to the current Chart
     * 
     * 
     * @param object $poSerie
     */
    public function addSerie(CHCSeries $poSerie)
    {
        if (!$poSerie instanceof CHCSeries) return false;
        
        $this->m_aoSeries[] = $poSerie;
    }
    
    
    /**
     * Render the JS - JSON et the container and return it as a single String
     */
    public function getDisplay()
    {
        $sJS = '';
        
        $asJS = array();
        $asJS['chart']     = $this->getData();
        $asJS['title']     = $this->setTitle->getData();
        $asJS['subtitle']  = $this->setSubTitle->getData();
        $asJS['xAxis']     = $this->setXAxis->getData();
        $asJS['yAxis']     = $this->setYAxis->getData();
        $asJS['tooltip']   = $this->setTooltip->getData();
        $asJS['legend']    = $this->setLegend->getData();
        
        $asSeries = array();
        foreach ($this->m_aoSeries as $oSerie)
            $asSeries[] = $oSerie->getData();
            
        $asJS['series']    = $asSeries;
        
            $sJS .= '
                jQuery(document).ready
                (
                	function() 
                	{
                		var chart = new Highcharts.Chart('.$this->jsonEncode($asJS).');
                	}
                );
            ';	

        $sJSString = $this->getJS($sJS);
        
        // Use of a javascript call collector
        if(class_exists('CSJavascriptManager'))
        {
            CSJavascriptManager::addBodyInstructions($sJS);
            return '<div id="'.$this->getId().'"></div>';
        }
        // use "as it" - you need to manually include the container and specify its id with the setId() Method
        else 
        {
            return $sJSString;
        }       
    }
    
    
    /**
     * A Wrapper function to call the php-built json_encode function 
     * wich handle the tokenized strings (especially js calls / js object) 
     *  
     * @param $psJS
     */
    public function jsonEncode($psJS)
    {
        $sJSON = json_encode($psJS);
        
        foreach (self::$sm_asTokenizer as $sToken => $sString) 
        {
        	$sJSON = str_replace('"'.$sToken.'"', $sString, $sJSON);
        }
        
        return $sJSON;
    }
    
    
	/**
	 * return the correct javascript tags for $psJS
	 * 
	 * @return STRING 
	 * @param $psJS string
	 */
	 public static function getJS($psJS)
	 {
	 	if (!is_string($psJS) || empty($psJS) ) return false;
	 	
	 	$sHTML = "\n".'<script type="text/javascript">'."\n";
	 	$sHTML .= '//<![CDATA['."\n";
	 	$sHTML .= $psJS."\n";
	 	$sHTML .= '//]]>'."\n";
	 	$sHTML .= '</script>'."\n";
	 	
	 	return $sHTML;	
	 }
}

?>